\documentclass[10pt]{sigplanconf}

\usepackage{color}
%\usepackage{doi}
\usepackage{listings}
\usepackage{paralist}

\setlength{\parskip}{0cm}
%\setlength{\parindent}{1em}

\definecolor{mylightgray}{RGB}{220,220,220}
\definecolor{mygray}{RGB}{128,128,128}
\definecolor{mydarkgray}{RGB}{96,96,96}

\newcommand{\term}[1]{\emph{#1}}
\newcommand{\subterm}[2]{\emph{#2}}

\DeclareRobustCommand{\Cpp}{C\texttt{++}}
\DeclareRobustCommand{\code}[1]{{\lstinline[breaklines=false,escapechar=@]{#1}}}
\DeclareRobustCommand{\codebr}[1]{{\lstinline[breaklines=true]{#1}}}
\DeclareRobustCommand{\codehaskell}[1]{{\lstinline[breaklines=false,language=Haskell]{#1}}}
\DeclareRobustCommand{\codeocaml}[1]{{\lstinline[breaklines=false,language=Caml]{#1}}}
\DeclareRobustCommand{\concept}[1]{{\small\textsc{#1}}}

\newcommand{\exclude}[1]{}
\newcommand{\halfline}{\vspace{-1.5ex}}

\lstdefinestyle{C++}{language=C++,%
showstringspaces=false,
  columns=fullflexible,
  escapechar=@,
  basicstyle=\sffamily,
%  commentstyle=\rmfamily\itshape,
  commentstyle=\color{mygray},   % gray comments
  stringstyle=\color{mydarkgray}\rmfamily\itshape, % string literals in italics
  aboveskip=\medskipamount, % the space above displayed listings (\medskipamount)
  belowskip=\medskipamount, % the space below displayed listings (\medskipamount)
  lineskip=-1pt,            % additional space between lines in listings (0pt)
  moredelim=**[is][\color{white}]{~}{~},
  morekeywords={axiom,concept,constexpr,decltype,noexcept,nullptr,requires,static_assert},
  literate={[<]}{{\textless}}1      {[>]}{{\textgreater}}1 %
           {[<<]}{{$\ll$ }}2        {[>>]}{{$\gg$ }}2 %
           {*}{{$*$}}1 % Without this, star (*) is rendered in Type 3 font
           %{_}{{\textunderscore}}1 %
           {<}{{$\langle$}}1        {>}{{$\rangle$}}1 %
           {<=}{{$\leq$}}1          {>=}{{$\geq$}}1 %
           {==}{{$==$}}2            {!=}{{$\neq$}}1 %
           {=>}{{$\Rightarrow\;$}}1 {->}{{$\rightarrow{}$}}1 %
           {...}{{$\ldots$}}3
           {<:}{{$\subtype{}\ $}}1  {<-}{{$\leftarrow$}}1 %
           {s1;}{{$s_1$;}}3 {s2;}{{$s_2$;}}3 {s3;}{{$s_3$;}}3 {s4;}{{$s_4$;}}3 {s5;}{{$s_5$;}}3 {s6;}{{$s_6$;}}3 {s7;}{{$s_7$;}}3 {sn;}{{$s_n$;}}3 {si;}{{$s_i$;}}3%
           {P1}{{$P_1$}}2 {P2}{{$P_2$}}2 {P3}{{$P_3$}}2 {P4}{{$P_4$}}2 {P5}{{$P_5$}}2 {P6}{{$P_6$}}2 {P7}{{$P_7$}}2 {Pn}{{$P_n$}}2 {Pi}{{$P_i$}}2%
           {D1}{{$D_1$}}2 {D2}{{$D_2$}}2 {D3}{{$D_3$}}2 {D4}{{$D_4$}}2 {D5}{{$D_5$}}2 {D6}{{$D_6$}}2 {D7}{{$D_7$}}2 {Dn}{{$D_n$}}2 {Di}{{$D_i$}}2%
           {T1}{{$T_1$}}2 {T2}{{$T_2$}}2 {T3}{{$T_3$}}2 {T4}{{$T_4$}}2 {T5}{{$T_5$}}2 {T6}{{$T_6$}}2 {T7}{{$T_7$}}2 {Tn}{{$T_n$}}2 {Ti}{{$T_i$}}2 {Tm}{{$T_m$}}2%
           {e1}{{$e_1$}}2 {e2}{{$e_2$}}2 {e3}{{$e_3$}}2 {e4}{{$e_4$}}2%
           {E1}{{$E_1$}}2 {E2}{{$E_2$}}2 {E3}{{$E_3$}}2 {E4}{{$E_4$}}2%
           {_1}{{$_1$}}1  {_2}{{$_2$}}1  {_3}{{$_3$}}1  {_4}{{$_4$}}1  {_ii}{{$_i$}}1  {_nn}{{$_n$}}1  {_N}{{$_N$}}1%
           {[_1]}{{\_1}}2  {[_2]}{{\_2}}2 %
           {m_e1}{{$m\_e_1$}}4 {m_e2}{{$m\_e_2$}}4 {m_e3}{{$m\_e_3$}}4 {m_e4}{{$m\_e_4$}}4%
           {aa}{{$a$}}1 {bb}{{$b$}}1 {Cc}{{$c$}}1 {Dd}{{$d$}}1 {ff}{{$f$}}1 {mm}{{$m$}}1%
           {Ss}{{$s$}}1 {Tt}{{$t$}}1 {vv}{{$v$}}1 {xx}{{$x$}}1 {yy}{{$y$}}1 {zz}{{$z$}}1%
           {Divide}{{Divide}}6 {Either}{Either}6 %
           {Times}{{Times}}5 %
           {Match}{{\emph{Match}}}5 %
           {Case}{{\emph{Case}}}4 %
           {Qua}{{\emph{Qua}}}3 %
           {When}{{\emph{When}}}4 %
           {Otherwise}{{\emph{Otherwise}}}9 %
           {EndMatch}{{\emph{EndMatch}}}8 %
           {CM}{{\emph{CM}}}2 {KS}{{\emph{KS}}}2 {KV}{{\emph{KV}}}2 %
           {EuclideanDomain}{\concept{EuclideanDomain}}{15}  %
           {LazyExpression}{\concept{LazyExpression}}{14}    %
           {Polymorphic}{\concept{Polymorphic}}{11}          %
           {CopyConstructible}{\concept{CopyConstructible}}{17}%
           {MoveConstructible}{\concept{MoveConstructible}}{17}%
           {EqualityComparable}{\concept{EqualityComparable}}{18}%
           {Copyable}{\concept{Copyable}}8                   %
           {Convertible}{\concept{Convertible}}{11}          %
           {Integral}{\concept{Integral}}8                   %
           {SameType}{\concept{SameType}}8                   %
           {Pattern}{\concept{Pattern}}7                     %
           {Regular}{\concept{Regular}}7                     %
           {Field}{\concept{Field}}5                         %
}
\lstset{style=C++}

\lstdefinestyle{Haskell}{language=Haskell,%
  morekeywords={out,view,real},
  literate={=>}{{$\Rightarrow\;$}}1 {->}{{$\rightarrow{}$}}1 {<-}{{$\leftarrow$}}1 {\\}{{$\lambda$}}1,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}

\lstdefinestyle{GJ}{language=Java,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}
\lstdefinestyle{Eiffel}{language=Eiffel,%
  literate={->}{{$\rightarrow$}}1,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}
\lstdefinestyle{Csharp}{language=[Sharp]C,
  morekeywords={where,require,type},
  literate={->}{{$\rightarrow{}$}}1,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}

\lstdefinestyle{ML}{language=ML,%
  literate={->}{{$\rightarrow{}$}}1,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}

\lstdefinestyle{Caml}{language=[Objective]Caml,%
  morekeywords={when},
  literate={->}{{$\rightarrow{}$}}1,
  moredelim=**[is][\color{red}]{`}{`},
  moredelim=**[is][\color{white}]{~}{~}
}

\lstdefinelanguage{scala}{% 
   morekeywords={% 
                try, catch, throw, private, public, protected, import, package, implicit, final, package, trait, type, class, val, def, var, if, this, else, extends, with, while, new, abstract, object, requires, case, match, sealed,override},% 
   sensitive=t, % 
   morecomment=[s]{/*}{*/},morecomment=[l]{\//},% 
   escapeinside={/*\%}{*/},%
   rangeprefix= /*< ,rangesuffix= >*/,%
   morestring=[d]{"}% 
}
 
\lstdefinelanguage{Haskell}{%
   otherkeywords={=>},%
   morekeywords={abstype,break,class,case,data,deriving,do,else,if,instance,newtype,of,out,real,return,then,view,where},%
   sensitive,%
   morecomment=[l]--,%
   morecomment=[n]{\{-}{-\}},%
   morestring=[b]"%
   literate=
   {=>}{$\Rightarrow$}{2}
   {->}{$\to$}{2}
   {-(+)>}{$\toplus$}{2}  
   {-(-)>}{$\tominus$}{2}  
   {<-}{$\leftarrow$}{2}
   % {\\}{$\lambda$}{1}
   {<~}{$\prec$}{2}
   {<|}{$\triangleleft$}{2}
   {<:}{$<:$}{1}
}

\lstloadlanguages{C++,Haskell,[Objective]Caml,XML,ML}


%% grammar commands
\newcommand{\Rule}[1]{{\rmfamily\itshape{#1}}}
\newcommand{\Alt}{\ensuremath{\mid}}
\newcommand{\SynCat}[1]{\ensuremath{\mathit{#1}}}
\newcommand{\is}{\ensuremath{::=}}
\newcommand{\subtype}{\ensuremath{\texttt{\raisebox{-0.1ex}{<}\raisebox{0.05ex}{:}}}}
\newcommand{\subtypeD}{\ensuremath{\subtype_d}}
\newcommand{\subobj}{\ensuremath{\lessdot}}
\newcommand{\lazyevals}{\Downarrow}
\newcommand{\evals}{\Rightarrow}
\newcommand{\evalspp}{\Rightarrow^+}
\newcommand{\DynCast}[2]{\ensuremath{\mathsf{dyn\_cast}\langle{#1}\rangle({#2})}}
\newcommand{\nullptr}{\ensuremath{\bot}}
\newcommand{\of}[1]{\left(#1\right)}
\newcommand{\tpl}[1]{\ensuremath{\langle#1\rangle}}
\newcommand{\Tpl}[1]{\ensuremath{\boldsymbol{\langle#1\rangle}}}
\newcommand{\True}{\ensuremath{\mathsf{true}}}
\newcommand{\False}{\ensuremath{\mathsf{false}}}

\newcommand{\CWildcard}{\ensuremath{\mathit{\bf wildcard}}}
\newcommand{\CValue}   {\ensuremath{\mathit{\bf value}}}
\newcommand{\CVariable}{\ensuremath{\mathit{\bf var}}}
\newcommand{\CExpr}    {\ensuremath{\mathit{\bf expr}}}
\newcommand{\CGuard}   {\ensuremath{\mathit{\bf guard}}}
\newcommand{\CCnstr}   {\ensuremath{\mathit{\bf ctor}}}

\newcommand{\Wildcard}   {\ensuremath{\CWildcard}}
\newcommand{\Value}[1]   {\ensuremath{\CValue\langle{#1}\rangle}}
\newcommand{\Variable}[1]{\ensuremath{\CVariable\langle{#1}\rangle}}
\newcommand{\ExprU}[2]   {\ensuremath{\CExpr\langle{#1},{#2}\rangle}}
\newcommand{\ExprB}[3]   {\ensuremath{\CExpr\langle{#1},{#2},{#3}\rangle}}
\newcommand{\ExprK}[3]   {\ensuremath{\CExpr\langle{#1},{#2},\cdots,{#3}\rangle}}
\newcommand{\Guard}[2]   {\ensuremath{\CGuard\langle{#1},{#2}\rangle}}
\newcommand{\Cnstr}[3]   {\ensuremath{\CCnstr\langle{#1},{#2},\cdots,{#3}\rangle}}

\definecolor{gray}{rgb}{0.5,0.5,0.5}

\newcommand{\f}[1]{{{\bf \underline{#1\%}}}}
\newcommand{\s}[1]{{ {#1\%}}}
\newcommand{\n}[1]{{ {\bf ~ ~ ~ ~ }}}
\newcommand{\none}{{ {\color{gray}0.00\%}}}
\newcommand{\Opn}{{\scriptsize {\bf Open}}}
\newcommand{\Cls}{{\scriptsize {\bf Tag}}}
\newcommand{\Unn}{{\scriptsize {\bf Union}}}

%\input{data2}

\newsavebox{\sembox}
\newlength{\semwidth}
\newlength{\boxwidth}

\newcommand{\Sem}[1]{%
\sbox{\sembox}{\ensuremath{#1}}%
\settowidth{\semwidth}{\usebox{\sembox}}%
\sbox{\sembox}{\ensuremath{\left[\usebox{\sembox}\right]}}%
\settowidth{\boxwidth}{\usebox{\sembox}}%
\addtolength{\boxwidth}{-\semwidth}%
\left[\hspace{-0.3\boxwidth}%
\usebox{\sembox}%
\hspace{-0.3\boxwidth}\right]%
}

\newcommand{\authormodification}[2]{{\color{#1}#2}}
\newcommand{\ys}[1]{\authormodification{blue}{#1}}
\newcommand{\bs}[1]{\authormodification{red}{#1}}
\newcommand{\gdr}[1]{\authormodification{magenta}{#1}}

\begin{document}

 \permissiontopublish
 \conferenceinfo{SPLASH~'13}{October 26--31, 2013, Indianapolis, Indiana, USA} 
 \copyrightyear{2013} \copyrightdata{978-1-4503-1995-9/13/10} 
 \doi{2508075.2508098}
 % insert the doi number of your paper from the confirmation 
 % email from rightsreview@acm.org

\titlebanner{Extended Abstract for OOPSLA 2013}        % These are ignored unless
\preprintfooter{Y.Solodkyy, G.Dos Reis, B.Stroustrup: Open Pattern Matching for \Cpp{}}   % 'preprint' option specified.

\title{Open Pattern Matching for \Cpp{}}
%\subtitle{your \code{visit}, Jim, is not \code{accept}able anymore}
%\subtitle{\code{accepting} aint no \code{visit}ors}

\authorinfo{Yuriy Solodkyy\and Gabriel Dos Reis\and Bjarne Stroustrup}
           {Texas A\&M University\\ Texas, USA}
           {\{yuriys,gdr,bs\}@cse.tamu.edu}

\maketitle

\begin{abstract}
\term{Pattern matching} is an abstraction mechanism that can greatly simplify source code. We 
present functional-style pattern matching for \Cpp{} implemented as a library, 
called \emph{Mach7}\footnote{The library is available at http://parasol.tamu.edu/mach7/}. 
All the patterns are user-definable, can be stored in variables, passed among functions,
and allow the use of open class hierarchies.
As an example, we implement common patterns used in functional languages.
\end{abstract}

\category{D.3.3}{Programming Languages}{Language Constructs and Features}
\category{D.1.5}{Programming techniques}{Object-oriented Programming}

%\terms
%Languages, Design

\keywords
Pattern Matching, \Cpp{}, Expression Problem

\section{Introduction} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:intro}

Pattern matching is an abstraction mechanism popularized by the functional
programming community, such as ML, OCaml and Haskell,
and recently adopted by object-oriented programming 
languages such as Scala, F\#, and dialects of 
\Cpp{} and Java. It provides syntax very close to mathematical notation 
and allows the user to describe tersely a (possibly infinite) set of values 
accepted by the \term{pattern}. 

We present functional-style pattern matching for \Cpp{} built as an ISO 
\Cpp{}11 library. Our solution:

\begin{compactitem}
\setlength{\itemsep}{0pt}
\setlength{\parskip}{0pt}
  \item Is \emph{open} to introduction of new patterns into the library, while not 
        making any assumptions about existing ones.
  \item Is \emph{type safe}: inappropriate applications of patterns to subjects are compile-time errors.
  \item Makes patterns \emph{first-class} citizens in the language.
  \item Is \emph{non-intrusive} and can be retroactively applied to existing types, both built-in and user-defined.
  \item Provides a \emph{unified syntax} for dealing with various encodings of 
        extensible hierarchical datatypes in \Cpp{}.
  \item Provides an alternative interpretation of the controversial \emph{n+k 
        patterns} (in line with that of constructor patterns), leaving the choice 
        of exact semantics to the user.
  \item Supports a limited form of \emph{views}.
  \item Generalizes open type switch to \emph{multiple scrutinees} and enables patterns 
        in case clauses.
%  \item Is simpler than conventional object-oriented or union-based alternatives.
%  \item Improves performance compared to alternatives in real applications~\cite{TypeSwitch}.
  \item Demonstrates that \emph{compile-time composition} of patterns through 
        concepts is superior to run-time composition of patterns through 
        polymorphic interfaces in terms of performance, expressiveness and 
        static type checking.
\end{compactitem}

%The library in this respect is nothing else than a set of \Cpp{} concepts 
%guiding the composition of patterns combined with a set of macros providing a 
%suitable surface syntax. 

%We observe that the approach we use for open type switching generalizes easily 
%to the case of multiple scrutinees (subjects), while the closed approach does 
%not.

\noindent
The library sets a standard for performance, extensibility, brevity, 
clarity and usefulness of any language solution for pattern matching.
It provides full functionality, so we can experiment with pattern matching in 
\Cpp{} and compare it to existing alternatives. Our solution requires only 
current support of \Cpp{}11 without any additional tool support.

\section{Pattern Matching in \Cpp{}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:cpppat}

As an example of syntax, enabled by \emph{Mach7}, we present here a complete 
implementation of an evaluator in $\lambda$-calculus:

\begin{lstlisting}[columns=flexible]
struct Term       { virtual @$\sim$@Term() {} };
struct Var : Term { std::string name; };
struct Abs : Term { Var&  var;  Term& body; };
struct App : Term { Term& func; Term& arg; };
@\halfline@
Term* eval(Term* t) {
  var<const Var&> v; var<const Term&> b,a;
  Match(*t) {
   Case(C<Var>())              return &match0;
   Case(C<Abs>())              return &match0;
   Case(C<App>(C<Abs>(v,b),a)) return eval(subs(b,v,a));
   Otherwise() std::cerr [<<] "error"; return nullptr;
  } EndMatch
}
\end{lstlisting}

\noindent
This corresponds directly to a functional language solution involving algebraic 
data types, which are encoded here with polymorphic classes. The solution is 
open to class extensions, including those due to dynamic linking, as well as 
fully supports generic multiple inheritance of \Cpp{}. The statement also 
accepts multiple \term{scrutinees} to allow for relational checks as demonstrated by 
the following functional solution to balancing red-black trees:
\begin{lstlisting}[keepspaces]
class T {enum Color {blk,red} col; T* lt; K key; T* rt;};
@\halfline@
T* balance(T::Color color, T* l, const K& key, T* r) {
  const T::Color B = T::Color::blk, R = T::Color::red;
  var<T*> aa, bb, Cc, Dd; var<K&> xx, yy, zz; T::Color col;
  Match(color, l, key, r) {
    Case(B, C<T>(R, C<T>(R, aa, xx, bb), yy, Cc), zz, Dd) ...
    Case(B, C<T>(R, aa, xx, C<T>(R, bb, yy, Cc)), zz, Dd) ...
    Case(B, aa, xx, C<T>(R, C<T>(R, bb, yy, Cc), zz, Dd)) ...
    Case(B, aa, xx, C<T>(R, bb, yy, C<T>(R, Cc, zz, Dd))) ...
    Case(col, aa, xx, bb) return new T{col, aa, xx, bb};
  } EndMatch
}
\end{lstlisting}

\noindent
The \code{...} in the first four case clauses above stands for: \\
\code{return new T\{R, new T\{B,aa,xx,bb\}, yy, new T\{B,Cc,zz,Dd\}\};}.

Built-in types can be analyzed and decomposed through pattern matching too. The 
following example defines a function for fast computation of Fibonacci numbers 
with so called ``n+k patterns'' given here an \term{equational interpretation} of 
\term{application patterns}:

\begin{lstlisting}[keepspaces]
int fib(int n) {
  var<int> mm;
  Match(n) {
   Case(1)         return 1;     
   Case(2)         return 1;
   Case(2*mm)     return sqr(fib(mm+1)) - sqr(fib(mm-1));
   Case(2*mm+1) return sqr(fib(mm+1)) + sqr(fib(mm));
  } EndMatch
}
\end{lstlisting}

\noindent
The solution is not bound to such equational interpretation. Instead, we offer 
to look at n+k patterns as mathematical notation that can be used to decompose 
various mathematical objects into subcomponents in much the same way as 
constructor patterns decompose algebraic data types.

\section{Implementation} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:impl}

Our \code{Match}-statement extends the efficient type switch for 
\Cpp{}~\cite{TS12}. The core of this extension amounts to handling of
multiple subjects (both polymorphic and non-polymorphic) as well as the ability 
to accept patterns in case clauses. %We use Morton order (bit interleaving) to 
%map a combination of arguments to a single hash, which still maintains the 
%favorable hashing properties the original type switch benefited from. The 
%library first uses polymorphic arguments for efficient type switching on 
%multiple arguments, and only then resorts to naive backtracking for 
%non-polymorphic ones.

Our approach to open patterns is based on compile-time composition of 
pattern objects through \term{concepts}, using a common \Cpp{} technique -- \term{expression 
templates}~\cite{Veldhuizen95expressiontemplates}. We demonstrate in~\cite{SolodkyyThesis}
that it is superior (in terms of performance and expressiveness) to previous 
approaches based on run-time composition of pattern objects through \term{interfaces}. 
In particular, the average overhead of our approach in comparison to a 
handcrafted solution is 25\%, occasionally becoming even faster by about 10\%. 
The average overhead of the approaches based on run-time composition (timed on 
the same examples) is 934\%. Neither of the approaches introduces a noticeable 
compile-time overhead.

\section{Evaluation Methodology} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:eval}

We performed several independent studies of our approach to demonstrate its 
effectiveness. The results of most of these studies are shown on the 
accompanying poster.

The first study compares our approach to the visitor design pattern, while the 
second does a similar comparison to built-in facilities of Haskell and OCaml. In 
the third study, we looked at the efficiency of hashing used in type switching 
on up to four scrutinees on some large real-world class hierarchies. In the 
fourth study, we compare the performance of matching $N$ polymorphic arguments 
against double, triple and quadruple dispatch via visitor design pattern as well 
as open multi-methods extension to \Cpp{}~\cite{OpenMM}.
In the fifth study we estimate the overhead of our and existing solutions to 
open patterns in comparison to a handcrafted code, while in the sixth study we 
compare their impact on the compilation times. In the last study, we rewrote two 
existing applications in order to compare performance, memory footprint, the 
ease of use, readability, maintainability etc. of each solution in a real 
application. The first application was a visitor-based \Cpp{} pretty-printer, 
while the second was a peephole optimizer written in Haskell.

\section{Conclusions and Future Work} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:cc}

The \emph{Mach7} library provides functional-style pattern-matching facilities 
for \Cpp{}. The solution is open to new patterns, with the traditional patterns 
implemented as examples. It is non-intrusive and can be applied retroactively. 
The library provides efficient and expressive matching on multiple scrutinees and 
compares well to multiple dispatch alternatives in terms of both time and space.
We also offer an alternative interpretation of the n+k patterns and show how some 
traditional generalizations of these patterns can be implemented in our library. 

In the future, we would like to implement an actual language extension capable of 
working with open patterns and look into how code can be optimized without 
hardcoding the knowledge of pattern's semantics into the compiler. 
%We would like to experiment with other kinds of patterns,  
%including those defined by the user; look at the interaction of patterns with 
%other facilities in the language and the standard library; make
%views less ad hoc etc.

We refer the reader to the first author's PhD thesis~\cite{SolodkyyThesis} as 
well as an accompanying paper~\cite{OPM13} for a detailed discussion of our 
solution to open and efficient pattern matching in \Cpp{}.

%\balance
\bibliographystyle{abbrv}
%\bibliographystyle{abbrvnat}
\bibliography{mlpatmat}

\end{document}
